#!/usr/bin/env python
#  Copyright (C) 2008 Monadsphere <monadli@gmail.com>
#
# This file is part of Monadsphere.
#
# Monadsphere is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Monadsphere is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Monadsphere. If not, see <http://www.gnu.org/licenses/>.

'''
  HTML related classes.
'''

from monadsphere.core import *
from monadsphere.util import *

class HtmlDocument(Document):
  '''
    An HTML document is responsible for creating html elements.
  '''

  def createElementHandle(self, elm, tagName):
    return 'document.createElement("' + tagName + '")'

  def setElementId(self, elm, id = None):
    if (id is not None):
      Document.setElementId(self, elm, id)
      print elm + '.id="' + id + '"'


class HtmlElement(Element):
  '''
    Base class for an html element.
  '''

  def createHandle(self, val):
    '''
      Not allowed to create a native element w/o value
    '''
    if (val is not None):
      print 'var ' + self.name + '=' + val

  def setOptions(self, options):
    '''
      Sets any element specific options.
    '''

    if ('style' in options):
      for k, v in options['style'].iteritems():
        self.setStyle(k, v)

    if ('innerHTML' in options):
      self.setInnerHTML(options['innerHTML'])

  def setAttribute(self, name, value):
    print self + '.setAttribute("' + str(name) + '",' + StrWrap(value) + ')'

  def getAttribute(self, name):
    return Var(self.doc, self + '.getAttribute(' + StrWrap(name) + ')')

  def hasAttribute(self, name):
    return Var(self.doc, self + '.hasAttribute(' + StrWrap(name) + ')')

  def appendChild(self, child):
    print self + '.appendChild(' + child + ')'

  def getParentNode(self):
    '''
      override Element.getParentNode.
    '''
    return HtmlElement(self, doc, self + '.parentNode')

  def getFirstChild(self):
    return HtmlElement(self.doc, self + '.firstChild')

  def getLastChild(self):
    return HtmlElement(self.doc, self + '.lastChild')

  def setStyle(self, name, value):
    print self + '.style.' + name +'="' + value + '"'

  def setId(self, id):
    self.doc.setElementId(self, id)

  def setInnerHTML(self, value):
    '''
      Sets innerHTML.
    '''
    print self + '.innerHTML=' + StrWrap(value)

  def getInnerHTML(self):
    '''
      Returns innerHTML.
    '''
    return Var(self.doc, self + '.innerHTML')

  def addEventListener(self, type, listener, useCapture):
    '''
      override Element.addEventListener.
    '''

    p = HtmlEventListener(self.doc, listener);
    print self + '.addEventListener("' + type + '",' + p + ',' + 'false' + ')'

class HtmlTag(HtmlElement):

  @staticmethod
  def createTagType(tagName):
    '''
      Returns a class for a specific tagName.
      For example: HtmlElement.createTagType('div') creates a type for div.
    '''

    class tag(HtmlTag):
      def __init__(self, doc, rhs = None):
        HtmlTag.__init__(self, doc, tagName)

    return tag

  def __init__(self, doc, tagName):
    self.tagName = tagName
    HtmlElement.__init__(self, doc)

  def createHandle(self, val = None):
    '''
      Creates a native handle. val is always ignored
    '''
    print 'var ' + self.name + '=' + self.doc.createElementHandle(self, self.tagName)

class Event(Var):
  def __init__(self, doc):
    self.name = 'event'
    self.doc = doc

  def getType(self):
    return Var(self.doc, self + '.type')

  def getTarget(self):
    return HtmlElement(self.doc, self + '.target')

class HtmlEventListener(EventListener):
  def __init__(self, doc, listener):
    EventListener.__init__(self, doc)
    event = Event(self.doc)
    print 'var ' + self + '= function(' + event + ') {'
    if (isinstance(listener, StringType)):
      execfile(listener)
    else:
      listener(event)
    print '}'
